package p.a2.a;

public class QuerPrime2 {

	public static long[] constructziffern(long[] p) {
		long[] tmp = { 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L };
		for (int i = 1; i < 10; i++) {
			if (p[i] > 0) {
				for (int k = 0; k < p[i]; k++) {
					tmp[i] = tmp[i] + (i * (long) Math.pow(10, k));
				}
			}
		}

		return tmp;
	}

	public static void outp(String l, long[] p, String r) {
		System.out.print(l + ": ");
		for (int i = 1; i < 10; i++) {
			System.out.print(p[i] + " ");
		}
		System.out.print(" " + r);
	}
	
	public static void outs(String l) {
		System.out.print(l);
	}
	
	public static long[] potenz(long[] p) {
		long[] tmp = { 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L };

		for (int i = 1; i < 10; i++) {
			if (p[i] > 0) {
				tmp[i] = (long) Math.pow(i, p[i]);
			}
		}

		return tmp;
	}

	public static long[] zuweisen(long v1, long v2, long v3, long v4, long v5, long v6, long v7, long v8, long v9) {
		long[] tmp = { 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L };

		tmp[0] = 0L;
		tmp[1] = v1;
		tmp[2] = v2;
		tmp[3] = v3;
		tmp[4] = v4;
		tmp[5] = v5;
		tmp[6] = v6;
		tmp[7] = v7;
		tmp[8] = v8;
		tmp[9] = v9;
		
		return tmp;
	}

	public static long concat(long[] p) {
		long tmp = 0L;
		String dummy = "";
		for (int i = 1; i < 10; i++) {
			if (p[i] > 0) {
				dummy = dummy + p[i];
			}
		}

		if (dummy != "") {
			tmp = Long.parseLong(dummy);
		}

		return tmp;
	}
	
	public static long ausmultiplizieren(long[] p) {
		long tmp = 1L;
		for (int i = 1; i < 10; i++) {
			if (p[i] > 0) {
				tmp = tmp * p[i];
			}
		}

		return tmp;
	}

	public static long auspotenzieren(long[] p) {
		long tmp = 1L;
		// outs("Potenz:");
		for (int i = 1; i < 10; i++) {
			if (p[i] > 0) {
				tmp = tmp * ((long) Math.pow(i, p[i]));
				// outs(" " + i + "^" + p[i] + "=" + ((long) Math.pow(i,
				// p[i])));
			}
		}
		
		return tmp;
	}
	
	public static long[] shorten(long[] p) {
		long[] tmp = { 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L };
		long d = 0L;

		for (int i = 0; i < 10; i++) {
			tmp[i] = p[i];
		}

		// outp(" Start:", tmp, "");
		d = tmp[2] / 3;
		tmp[8] = tmp[8] + d;
		tmp[2] = tmp[2] - (3 * d);
		// outp(" 3*2->8:", tmp, "");
		d = tmp[3] / 2;
		tmp[9] = tmp[9] + d;
		tmp[3] = tmp[3] - (2 * d);
		// outp(" 2*3->9:", tmp, "");
		d = Math.min(tmp[2], tmp[3]);
		tmp[6] = tmp[6] + d;
		tmp[2] = tmp[2] - d;
		tmp[3] = tmp[3] - d;
		// outp(" 2*3->6:", tmp, "");
		d = (tmp[2] / 2);
		tmp[4] = tmp[4] + d;
		tmp[2] = tmp[2] - (2 * d);
		// outp(" 2*2->4:", tmp, "");
		return tmp;
	}

	public static int mp(long[] p) {
		int grad = 0;
		long produkt = 0;
		long z = 0;
		
		z = auspotenzieren(p);
		// outs(" z:" + z);
		do {
			produkt = 1;
			grad++;
			while (z != 0) {
				produkt = produkt * (z % 10);
				z = z / 10;
			}
			z = produkt;
		} while (produkt >= 10); // schleife solange bis das Querrodukt
		// einstellig ist
		// System.out.println("x:" + zahl + " produkt:" + produkt + " g:" +
		// grad);
		return grad;
	}
	
	public static void main(String[] args) {

		// int Kmax = Integer.parseInt(args[0]); // argumentenübername
		int Kmax = 12;
		int MaxExp = 10; // max 19
		int qpgrad = 0;

		long LongMax = (long) Math.pow(2, 62);
		long number = 0L;
		long[] ziffernmenge, faktoren, exponent = { 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L };
		long[][] resultatexponent = new long[12][10];
		long[] resultat = { LongMax, LongMax, LongMax, LongMax, LongMax, LongMax, LongMax, LongMax, LongMax, LongMax, LongMax, LongMax };
		
		for (int i = 0; i < 12; i++) {
			for (int k = 0; k < 10; k++) {
				resultatexponent[i][k] = 0L;
			}
		}

		long startZeit = System.currentTimeMillis(); // stopuhr

		for (int p2 = 0; p2 <= MaxExp; p2++) {
			for (int p3 = 0; p3 <= MaxExp; p3++) {
				for (int p7 = 0; p7 <= MaxExp; p7++) {
					if (p2 > 1) {
						for (int p5 = 0; p5 <= MaxExp; p5++) {

							exponent = zuweisen(0L, p2, p3, 0L, p5, 0L, p7, 0L, 0L);
							outp("Exponenten", exponent, " ");

							exponent = shorten(exponent);
							outp("Reduziert", exponent, " ");

							// faktoren = potenz(exponent);
							// outp("Faktoren", faktoren, " ");

							qpgrad = mp(exponent);
							outs(" MP:" + qpgrad);

							ziffernmenge = constructziffern(exponent);
							outp(" Ziffernmenge", ziffernmenge, " ");

							number = concat(ziffernmenge);

							if (resultat[qpgrad] > number) {
								resultat[qpgrad] = number;
								resultatexponent[qpgrad] = exponent;
								System.out.print("            NEW");
							}

							outs("\n");

							// outp("Faktoren", faktoren, "\n");
						}
					} else {
						exponent = zuweisen(0L, p2, p3, 0L, 0L, 0L, p7, 0L, 0L);
						outp("Exponenten", exponent, " ");
						
						exponent = shorten(exponent);
						outp("Reduziert", exponent, " ");
						
						// faktoren = potenz(exponent);
						// outp("Faktoren", faktoren, " ");

						qpgrad = mp(exponent);
						outs(" MP:" + qpgrad);

						ziffernmenge = constructziffern(exponent);
						outp(" Ziffernmenge", ziffernmenge, " ");
						
						number = concat(ziffernmenge);
						
						if (resultat[qpgrad] > number) {
							resultat[qpgrad] = number;
							resultatexponent[qpgrad] = exponent;
							System.out.print("            NEW");
						}

						outs("\n");

					}
				}
			}
		}
		System.out.println(" Zeit:" + ((System.currentTimeMillis() - startZeit)));
		for (int k = 1; k <= Kmax; k++) { // schleife k durchzählen bis kmax
			System.out.println(k + " Schritte: " + resultat[k]);
		}

	}
}